package demo;

import lombok.Data;
import org.junit.jupiter.api.Test;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zjq
 * @version 创建时间：2021-11-22 10:23:42
 */
public class streamTest2 {

    //已知学生、问题、学生问题成绩3个表  学生*问题>=学生问题成绩
    //组装成一个类似笛卡尔乘积的类
    @Test
    public void cartesian() {
        List<Student> studentList = new ArrayList<Student>();
        studentList.add(new Student(1, "1号"));
        studentList.add(new Student(2, "2号"));
        studentList.add(new Student(3, "3号"));
        studentList.add(new Student(4, "4号"));

        List<Question> questionList = new ArrayList<Question>();
        questionList.add(new Question(1, "问题1"));
        questionList.add(new Question(2, "问题2"));
        questionList.add(new Question(3, "问题3"));

        List<Score> scoreList = new ArrayList<Score>();
        scoreList.add(new Score(1, 1, 2, 10));
        scoreList.add(new Score(2, 1, 3, 10));
        scoreList.add(new Score(3, 2, 1, 20));
        scoreList.add(new Score(4, 2, 2, 30));

        List<StudentScore> studentScores = studentList.stream()
                .map(student -> {
                    StudentScore studentScore = new StudentScore();
                    studentScore.setId(student.getId());

                    List<StudentScoreDetail> scoreDetails = questionList.stream()
                            .map(question -> getScoreDetail(student, question, scoreList))
                            .filter(detail -> detail != null)
                            .collect(Collectors.toList());

                    studentScore.setMap(scoreDetails);
                    return studentScore;
                })
                .collect(Collectors.toList());

        System.out.println(studentScores);
    }

    private StudentScoreDetail getScoreDetail(Student student, Question question, List<Score> scoreList) {
        Optional<Score> score = scoreList.stream()
                .filter(s -> s.getStudentId() == student.getId() && s.getQuestionId() == question.getId())
                .findFirst();

        if (score.isPresent()) {
            StudentScoreDetail detail = new StudentScoreDetail();
            detail.setId(question.getId());
            detail.setScore(score.get().getScore());
            return detail;
        } else {
            return null;
        }
    }

    class Student {
        private int id;
        private String name;

        public Student(int id, String name) {
            this.id = id;
            this.name = name;
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    @Data
    class Score {
        private int id;
        private int studentId;
        private int questionId;
        private int score;

        public Score(int id, int studentId, int questionId, int score) {
            this.id = id;
            this.studentId = studentId;
            this.questionId = questionId;
            this.score = score;
        }

    }

    @Data
    class Question {
        private int id;
        private String question;

        Question(int id, String question) {
            this.id = id;
            this.question = question;
        }
    }

    @Data
    class StudentScore {
        private int id;
        private List<StudentScoreDetail> map;
    }

    @Data
    class StudentScoreDetail {
        private int id;
        private int score;
    }
}
